/// <reference path="../../Resources/js/jquery/jquery.debug.js" />
/// <reference name="MicrosoftAjax.debug.js" />

Type.registerNamespace("BM");

// DeterminacyOperator enum

BM.DeterminacyOperator = function() { };
BM.DeterminacyOperator.prototype =
{
    Exists: 0,
    NotExists: 1,
    Equals: 2,
    NotEquals: 3,
    GreaterThan: 4,
    GreaterThanEqual: 5,
    LessThan: 6,
    LessThanEqual: 7
}

BM.DeterminacyOperator.registerEnum("BM.DeterminacyOperator", false);


// Determinacy object

BM.Determinacy = function(item, data) {
    BM.Determinacy.initializeBase(this, [item, data]);
    item.addChanged(Function.createDelegate(this, this.run));
    item.addUnloaded(Function.createDelegate(this, this.run));
    item.addUsageChanged(Function.createDelegate(this, this.run));
    this.valueToCompare = this.getValueToCompare();
    this.dependantInfos = this.getDependantInfos();
    this.method = this.getMethod();
}

BM.Determinacy.prototype = {
    load: function() {
        this.run();
    },

    getMethod: function() {
        var value = this.getProperty('method');
        if (value == null || value == '') {
            value = "getValue";
        }
        return value;
    },

    getValueToCompare: function() {
        var value = this.getProperty('value');
        if (value && value.indexOf('|') != -1) {
            return value.split('|');
        } else {
            return value;
        }
    },

    getOperator: function() {
        if (this.operator == null) {
            this.operator = this.getProperty('operator')
        }
        return this.operator;
    },

    getDependantInfos: function() {
        return this.getProperty('dependants');
    },

    getDependants: function() {
        if (this.dependants == null) {
            this.dependants = new Array();
            for (var i = 0; i < this.getDependantInfos().length; i++) {
                this.appendDependants(this.getDependantInfos()[i]);
            }
        }
        return this.dependants;
    },

    appendDependants: function(dependantInfo) {
        var paths = dependantInfo.Path.split('|')
        for (var i = 0; i < paths.length; i++) {
            this.dependants.push(new BM.Dependant(this, paths[i].trim(), dependantInfo.Actions));
        }
    },

    run: function() {
        if (this.isConditionMatched()) {
            for (var i = 0; i < this.getDependants().length; i++) {
                this.getDependants()[i].run();
            }
        }
    },

    isConditionMatched: function() {
        if (!this.isItemUsed()) {
            return this.getOperator() == BM.DeterminacyOperator.NotExists;
        }
        if (this.getOperator() == BM.DeterminacyOperator.Exists) {
            return this.isItemUsed();
        }

        return this.compare();
    },

    isItemUsed: function() {
        if (MItem.getById(this.getItem().getId()) == null) {
            return false;
        }
        return this.getItem().isInUse();
    },

    compare: function() {
        var value = this.getDeterminacyValue();

        if (jQuery.isArray(this.getValueToCompare())) {
            return this.compareWithArray(this.getValueToCompare(), this.getOperator(), value);
        }

        return this.compareValues(this.getValueToCompare(), this.getOperator(), value);
    },

    getDeterminacyValue: function() {
        try {
            var value = this.getItem()[this.method]();
            return (value != null) ? value.toString() : '';
        } catch (e) {
            alert('No method ' + this.method + ' found');
        }
    },

    compareWithArray: function(array, operator, value) {
        switch (operator) {
            case BM.DeterminacyOperator.Equals:
                return this.isInArray(array, value);
            case BM.DeterminacyOperator.NotEquals:
                return !this.isInArray(array, value);
        }
        return false;
    },

    isInArray: function(array, value) {
        for (var i = 0; i < array.length; i++) {
            if (array[i].trim() == value) {
                return true;
            }
        }

        return false;
    },

    compareValues: function(first, operator, second) {
        switch (operator) {
            case BM.DeterminacyOperator.Equals:
                return first == second;
            case BM.DeterminacyOperator.NotEquals:
                return first != second;
            case BM.DeterminacyOperator.GreaterThan:
                return first > second;
            case BM.DeterminacyOperator.GreaterThanEqual:
                return first >= second;
            case BM.DeterminacyOperator.LessThan:
                return first < second;
            case BM.DeterminacyOperator.LessThanEqual:
                return first <= second;
        }
        return false;
    }
}

BM.Determinacy.registerClass("BM.Determinacy", BM.Addition);
